<template>
  <div class="chat-app">
    <div class="project-selector">
      <h3 style="text-align: center">项目聊天群</h3>
      <select
          v-model="selectedProject"
          @change="onProjectChange"
          class="custom-select"
      >
        <option disabled value="">请选择项目</option>
        <option
            v-for="project in projects"
            :key="project"
            :value="project"
        >
          {{ project }}
        </option>
      </select>
    </div>



    <div
        class="chat-container"
        @scroll="handleScroll"
        ref="chatContainer"
    >
      <div v-if="loading" class="loading-spinner"></div>

      <!-- 修改后的消息容器结构 -->
      <div
          v-for="message in messages"
          :key="message.id"
          :class="['message-container', { 'self-message': message.username === currentUser }]"
      >
        <!-- 头像和用户名 -->
        <div class="user-info">
          <img
              class="avatar"
              :src="getAvatarUrl(message.username)"
              alt=""
          />
          <span class="username">{{ message.username }}</span>
        </div>

        <!-- 消息气泡 -->
        <div class="message-bubble">
          <div class="message-content">{{ message.message }}</div>
          <span
              class="timestamp"
              :title="formatFullTime(message.data)"
          >
            {{ formatRelativeTime(message.data) }}
          </span>
        </div>
      </div>
    </div>

    <!-- 输入容器保持不变 -->
    <div class="input-container">
      <textarea
          v-model="newMessage"
          @keydown.enter.exact.prevent="sendMessage"
          @keydown.ctrl.enter.exact="newMessage += '\n'"
          placeholder="输入消息..."
          rows="1"
          class="message-input"
          @input="adjustTextareaHeight"
      ></textarea>
      <button
          @click="sendMessage"
          :disabled="!newMessage.trim()"
          class="send-button"
      >
        <span v-if="!sending">发送</span>
        <div v-else class="spinner"></div>
      </button>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import moment from 'moment'

export default {
  data() {
    return {
      projects: [],
      selectedProject: '',
      messages: [],
      newMessage: '',
      page: 1,
      loading: false,
      hasMore: true,
      ws: null,
      scrollHeight: 0,
      sending: false,
      user: JSON.parse(localStorage.getItem('honey-user') || '{}')
    }
  },
  computed: {
    currentUser() {
      return this.user.name || ''
    }
  },
  mounted() {
    this.loadProjects()
  },
  beforeUnmount() {
    if (this.ws) this.ws.close()
  },
  methods: {
    async loadProjects() {
      try {
        const res = await this.$request.get('/api/projects')
        this.projects = res.data
      } catch (error) {
        console.error('获取项目列表失败:', error)
        this.$toast.error('项目加载失败')
      }
    },

    async onProjectChange() {
      if (this.ws) this.ws.close()
      this.messages = []
      this.page = 1
      this.hasMore = true
      await this.loadHistory()
      this.setupWebSocket()
    },

    async loadHistory() {
      if (!this.hasMore || this.loading) return

      this.loading = true
      try {
        const container = this.$refs.chatContainer
        const originalScrollHeight = container.scrollHeight

        const response = await this.$request.get('/api/history', {
          params: {
            projectName: this.selectedProject,
            page: this.page,
            size: 20
          }
        })

        const newMessages = response.data.reverse()
        if (newMessages.length < 20) this.hasMore = false

        this.messages = [...newMessages, ...this.messages]
        this.page++

        this.$nextTick(() => {
          container.scrollTop = container.scrollHeight - originalScrollHeight
        })
      } catch (error) {
        console.error('加载历史记录失败:', error)
        this.$toast.error('历史记录加载失败')
      } finally {
        this.loading = false
      }
    },

    handleScroll(e) {
      const container = e.target
      if (container.scrollTop < 100 && this.hasMore) {
        this.loadHistory()
      }
    },

    setupWebSocket() {
      this.ws = new WebSocket(
          `http://localhost:9090/chat/${encodeURIComponent(this.selectedProject)}?username=${encodeURIComponent(this.currentUser)}`
      )

      this.ws.onmessage = (event) => {
        const message = JSON.parse(event.data)
        this.messages.push(message)
        this.$nextTick(() => {
          this.scrollToBottom()
        })
      }

      this.ws.onerror = (error) => {
        console.error('WebSocket错误:', error)
        this.$toast.error('连接异常，正在尝试重连...')
        setTimeout(() => this.setupWebSocket(), 3000)
      }

      this.ws.onclose = () => {
        console.log('WebSocket连接关闭')
      }
    },

    async sendMessage() {
      if (!this.newMessage.trim() || !this.ws) return

      this.sending = true
      try {
        await new Promise((resolve, reject) => {
          if (this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(JSON.stringify({
              message: this.newMessage.trim(),
              date: new Date().toISOString()
            }))
            resolve()
          } else {
            reject('WebSocket未连接')
          }
        })
        this.newMessage = ''
      } catch (error) {
        console.error('消息发送失败:', error)
        this.$toast.error('发送失败，请重试')
      } finally {
        this.sending = false
      }
    },

    scrollToBottom() {
      const container = this.$refs.chatContainer
      container.scrollTop = container.scrollHeight
    },

    formatRelativeTime(date) {
      return moment(date).fromNow()
    },

    formatFullTime(date) {
      return moment(date).format('YYYY-MM-DD HH:mm:ss')
    },
     getAvatarUrl(username) {
      try {
        const res =  this.$request.get(`/project/getAvatarUrl?username=${encodeURIComponent(username)}`);
        return res.data.avatar
      } catch (error) {
        return `https://csych.oss-cn-hangzhou.aliyuncs.com/user/2025/03/09/d63a87c2092648ea85070c2318b47140.jpg`
      }

    },
    adjustTextareaHeight(e) {
      e.target.style.height = 'auto'
      e.target.style.height = e.target.scrollHeight + 'px'
    }
  }
}

</script>

<style scoped>
/* 新增和修改的样式 */
.message-container {
  display: flex;
  align-items: flex-start;
  margin: 12px 20px;
  position: relative;
}

.message-container.self-message {
  flex-direction: row-reverse;
}

.user-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0 12px;
  width: 60px;
}

.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin-bottom: 4px;
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.username {
  font-size: 12px;
  color: #666;
  text-align: center;
  word-break: break-all;
  line-height: 1.2;
  max-width: 60px;
}

.message-bubble {
  max-width: 70%;
  padding: 10px 14px;
  border-radius: 5px;
  background: #ffffff;
  position: relative;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  min-width: 80px;
}

.message-container.self-message .message-bubble {
  background: #4a90e2;
  color: white;
}

.message-content {
  word-break: break-word;
  line-height: 1.5;
}

.timestamp {
  position: absolute;
  right: 8px;
  bottom: -18px;
  font-size: 10px;
  color: #999;
  white-space: nowrap;
}

.message-container.self-message .timestamp {
  right: auto;
  left: 8px;
}

.chat-app {
  max-width: 1300px;
  margin: 20px auto;
  padding: 20px;
  background: #f5f7fb;
  border-radius: 12px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.project-selector {
  margin-bottom: 20px;
}

.custom-select {
  width: 100%;
  padding: 10px 15px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  background: white;
  font-size: 16px;
  transition: border-color 0.3s ease;
}

.custom-select:focus {
  outline: none;
  border-color: #4a90e2;
}

.chat-container {
  height: 60vh;
  background: white;
  border-radius: 8px;
  padding: 20px;
  overflow-y: auto;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
}

.input-container {
  display: flex;
  gap: 12px;
  margin-top: 20px;
}

.message-input {
  flex: 1;
  padding: 12px 16px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  resize: none;
  max-height: 150px;
  font-size: 16px;
  transition: border-color 0.3s ease;
}

.message-input:focus {
  outline: none;
  border-color: #4a90e2;
}

.send-button {
  padding: 12px 24px;
  background: linear-gradient(135deg, #4a90e2, #306fcc);
  border: none;
  border-radius: 8px;
  color: white;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.3s ease;
}

.send-button:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

.loading-spinner {
  text-align: center;
  padding: 20px;
}

.loading-spinner::after {
  content: "";
  display: inline-block;
  width: 24px;
  height: 24px;
  border: 3px solid #4a90e2;
  border-radius: 50%;
  border-top-color: transparent;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.spinner {
  width: 20px;
  height: 20px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: white;
  animation: spin 0.8s linear infinite;
}
</style>